package pers.cj.pdos.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import pers.cj.pdos.entity.*;
import pers.cj.pdos.mapper.*;
import pers.cj.pdos.service.IGoodsTransferService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.stereotype.Service;
import pers.cj.pdos.utils.PdosUtils;
import pers.cj.pdos.utils.Utils;
import pers.cj.pdos.utils.UuidUtils;
import pers.cj.pdos.vo.GoodsTransferGoodsVo;
import pers.cj.pdos.vo.GoodsTransferVo;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author chenj
 * @since 2019-11-04
 */
@Service
public class GoodsTransferServiceImpl extends ServiceImpl<GoodsTransferMapper, GoodsTransfer> implements IGoodsTransferService {
    @Autowired
    GoodsTransferMapper goodsTransferMapper;
    @Autowired
    GoodsTransferGoodsMapper goodsTransferGoodsMapper;
    @Autowired
    GoodsStockMapper goodsStockMapper;
    @Autowired
    HouseWaitInMapper houseWaitInMapper;
    @Autowired
    HouseWaitInGoodsMapper houseWaitInGoodsMapper;
    @Autowired
    HouseWaitOutMapper houseWaitOutMapper;
    @Autowired
    HouseWaitOutGoodsMapper houseWaitOutGoodsMapper;
    @Autowired
    GoodsSnMapper goodsSnMapper;
    @Autowired
    GoodsSnLogMapper goodsSnLogMapper;

    @Autowired
    SettAccountMapper settAccountMapper;

    @Override
    public boolean checkNo(String no, String companyId) {
        return goodsTransferMapper.selectCount(new QueryWrapper<GoodsTransfer>().eq("no",no).eq("company_id",companyId)) > 0;
    }

    @Override
    public boolean checkClose(GoodsTransfer entity) {
        return goodsTransferMapper.selectCount(new QueryWrapper<GoodsTransfer>().eq("id",entity.getId()).eq("close",true)) > 0;
    }

    @Override
    public void insert(BusinessSet businessSet,
                       GoodsTransfer goodsTransfer,
                       List<GoodsTransferGoods> goodsTransferGoodsList,
                       List<GoodsSn> goodsSnList,
                       List<GoodsSnLog> goodsSnOutLogList,
                       List<GoodsSnLog> goodsSnInLogList) {
        goodsTransferMapper.insert(goodsTransfer);
        goodsTransferGoodsMapper.insertBatch(goodsTransferGoodsList);
        GoodsTransferVo vo = goodsTransferMapper.getVoById(goodsTransfer.getId());

        if (!Utils.isEmpty(vo.getSettAccountId()) && vo.getOtherAmt()!= null){
            //调拨其他费用 余额-
            settAccountMapper.addBalance(vo.getOtherAmt().negate(), vo.getSettAccountId());
        }

        if (!PdosUtils.houseInOut(businessSet)) {
            //未启用出入库
            //处理库存 出库仓库减少库存，入库仓库增加库存
            processGoodsStock(1, vo);

            //序列号需要把仓库id改成入库的仓库id,序列号状态为在库
            if (!Utils.isEmpty(goodsSnList)) {
                goodsSnMapper.inByList(vo.getInHouseId(), goodsSnList);
            }
            //添加序列号日志
            if (!Utils.isEmpty(goodsSnOutLogList)) {
                goodsSnLogMapper.insertBatch(goodsSnOutLogList);//先添加出库
            }
            if (!Utils.isEmpty(goodsSnInLogList)) {
                goodsSnLogMapper.insertBatch(goodsSnInLogList);//再添加入库
            }
        } else {
            //出入库管理。 先是生成待出库单；出库商品后更新调拨单出库状态，自动生成待入库单，入库后更新调拨单的入库状态。
            //待出库单
            processHouseWaitOut(1,vo);
        }
    }

    @Override
    public void close(GoodsTransfer goodsTransfer, BusinessSet businessSet) {
        GoodsTransferVo vo = goodsTransferMapper.getVoById(goodsTransfer.getId());

        if (!Utils.isEmpty(vo.getSettAccountId()) && vo.getOtherAmt()!= null){
            //调拨作废 其他费用 余额+
            settAccountMapper.addBalance(vo.getOtherAmt(), vo.getSettAccountId());
        }

        //直接出库的销售单，则需要去除相应的库存和sn。
        if (vo.getStatus() == 1) {
            processGoodsStock(2, vo);

            //商品要变成出库状态
            List<GoodsSn> goodsSnList = PdosUtils.genGoodsSnList(vo.getGoodsTransferGoodsVoList());
            if (!Utils.isEmpty(goodsSnList)) {
                goodsSnMapper.outByList(vo.getOutHouseId(), goodsSnList);
            }
        } else {
            //更新待出库单的关联单据的关闭状态
            processHouseWaitOut(2,vo);
        }
        GoodsTransfer temp = new GoodsTransfer();
        temp.setId(goodsTransfer.getId());
        temp.setClose(true);
        goodsTransferMapper.updateById(temp);


    }

    @Override
    public GoodsTransferVo getVoById(String id) {
        return goodsTransferMapper.getVoById(id);
    }

    @Override
    public List<GoodsTransferVo> listVoByIds(List<String> ids) {
        return goodsTransferMapper.listVoByIds(ids);
    }

    @Override
    public List<GoodsTransferVo> listVo(String companyId,
                                        Integer page,
                                        Integer limit,
                                        Boolean close,
                                        String search,
                                        String no,
                                        String goodsName,
                                        String remark,
                                        Date date1,
                                        Date date2,
                                        String outStoreId,
                                        String inStoreId,
                                        String userStoreId,
                                        String userId,
                                        Date makeTime1,
                                        Date makeTime2,
                                        String outHouseId,
                                        String inHouseId,
                                        String makeUserId,
                                        Integer outStatus,
                                        Integer inStatus) {
        return goodsTransferMapper.listVo(companyId,
                Utils.genPage(page,limit),
                limit,
                close,
                search,
                no,
                goodsName,
                remark,
                date1,
                date2,
                outStoreId,
                inStoreId,
                userStoreId,
                userId,
                makeTime1,
                makeTime2,
                outHouseId,
                inHouseId,
                makeUserId,
                outStatus,
                inStatus);
    }

    @Override
    public long count(String companyId,
                      Boolean close,
                      String search,
                      String no,
                      String goodsName,
                      String remark,
                      Date date1,
                      Date date2,
                      String outStoreId,
                      String inStoreId,
                      String userStoreId,
                      String userId,
                      Date makeTime1,
                      Date makeTime2,
                      String outHouseId,
                      String inHouseId,
                      String makeUserId,
                      Integer outStatus,
                      Integer inStatus){
        return goodsTransferMapper.count(companyId,close,
                search,
                no,
                goodsName,
                remark,
                date1,
                date2,
                outStoreId,
                inStoreId,
                userStoreId,
                userId,
                makeTime1,
                makeTime2,
                outHouseId,
                inHouseId,
                makeUserId,
                outStatus,
                inStatus);
    }


    /**
     * 处理待出库单
     * @param type 1新增调拨单 2作废调拨单
     * @param goodsTransferVo
     */
    private void processHouseWaitOut(int type, GoodsTransferVo goodsTransferVo) {
        if (type == 2) {
            //更新关联待出库单的关闭状态
            HouseWaitOut houseWaitOut = new HouseWaitOut();
            houseWaitOut.setClose(true);
            houseWaitOutMapper.update(houseWaitOut, new QueryWrapper<HouseWaitOut>().eq("goods_transfer_id", goodsTransferVo.getId()));


            HouseWaitIn houseWaitIn = new HouseWaitIn();
            houseWaitIn.setClose(true);
            houseWaitInMapper.update(houseWaitIn, new QueryWrapper<HouseWaitIn>().eq("goods_transfer_id", goodsTransferVo.getId()));
            return;
        }

        HouseWaitOut houseWaitOut = new HouseWaitOut();
        houseWaitOut.setId(UuidUtils.getUUID());
        houseWaitOut.setGoodsTransferId(goodsTransferVo.getId());
        houseWaitOut.setHouseId(goodsTransferVo.getOutHouseId());
        houseWaitOut.setClose(false);
        houseWaitOut.setStatus(1);//待出库
        houseWaitOut.setType(3);//设置类型为调拨
        houseWaitOut.setCompanyId(goodsTransferVo.getCompanyId());
        houseWaitOut.setTime(goodsTransferVo.getTime());
        houseWaitOutMapper.insert(houseWaitOut);

        List<HouseWaitOutGoods> houseWaitOutGoodsList = new ArrayList<>();
        for (GoodsTransferGoodsVo vo : goodsTransferVo.getGoodsTransferGoodsVoList()) {
            HouseWaitOutGoods houseWaitOutGoods = new HouseWaitOutGoods();
            houseWaitOutGoods.setId(UuidUtils.getUUID());
            houseWaitOutGoods.setHouseWaitOutId(houseWaitOut.getId());
            houseWaitOutGoods.setGoodsTransferGoodsId(vo.getId());
            houseWaitOutGoods.setGoodsId(vo.getGoodsId());
            houseWaitOutGoods.setHasOutNumber(new BigDecimal(0));
            houseWaitOutGoods.setWaitOutNumber(vo.getNumber());
            houseWaitOutGoods.setNumber(vo.getNumber());
            houseWaitOutGoods.setUnitId(vo.getUnitId());
            houseWaitOutGoods.setTimes(vo.getTimes());
            houseWaitOutGoods.setCompanyId(goodsTransferVo.getCompanyId());
            houseWaitOutGoodsList.add(houseWaitOutGoods);
        }
        houseWaitOutGoodsMapper.insertBatch(houseWaitOutGoodsList);
    }


    /**
     *
     * 处理库存
     * @param type 1新增调拨单 2作废调拨单
     * @param goodsTransferVo
     */
    private void processGoodsStock(int type, GoodsTransferVo goodsTransferVo) {
        List<GoodsStock> goodsStockList = new ArrayList<>();
        for ( GoodsTransferGoodsVo vo: goodsTransferVo.getGoodsTransferGoodsVoList()) {
            String goodsId = vo.getGoodsId();
            BigDecimal number = vo.getNumber().multiply(vo.getTimes());//数量*换算倍数
            if (type == 1) {
                //出库的
                goodsStockList.add(genGoodsStock(goodsId,number.negate(), goodsTransferVo.getOutHouseId(),goodsTransferVo.getCompanyId()));
                //入库的
                goodsStockList.add(genGoodsStock(goodsId,number, goodsTransferVo.getInHouseId(),goodsTransferVo.getCompanyId()));
            } else {
                //出库的
                goodsStockList.add(genGoodsStock(goodsId,number, goodsTransferVo.getOutHouseId(),goodsTransferVo.getCompanyId()));
                //入库的
                goodsStockList.add(genGoodsStock(goodsId,number.negate(), goodsTransferVo.getInHouseId(),goodsTransferVo.getCompanyId()));
            }
        }

        goodsStockMapper.insertBatch(goodsStockList);
    }

    private GoodsStock genGoodsStock(String goodsId, BigDecimal number, String houseId, String companyId){
        GoodsStock goodsStock = new GoodsStock();
        goodsStock.setId(UuidUtils.getUUID());
        goodsStock.setGoodsId(goodsId);
        goodsStock.setHouseId(houseId);
        goodsStock.setNum(number);
        goodsStock.setTime(new Date());
        goodsStock.setCompanyId(companyId);
        return goodsStock;
    }
}
